#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <semaphore.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    char* shm_value_name = "unnamed_sem_shm_value";
    char* sem_name = "/named_sem_shm";
    // 创建一个共享内存对象
    int value_fd = shm_open(shm_value_name,O_RDWR | O_CREAT, 0644);
    // 初始化有名信号量
    sem_t* sem = sem_open(sem_name, O_CREAT, 0666, 1);
    // 2、设置共享内存对象大小
    ftruncate(value_fd, sizeof(int));
    // 3、内存映射
    int* value = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, value_fd, 0);
    *value = 0;
    // 4、使用内存映射实现进程间的通讯
    pid_t pid = fork();
    if(pid < 0)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else if(pid == 0)
    {   
        // 子进程
        sem_wait(sem);
        // 信号量等待
        int tmp = *value + 1;
        sleep(1);
        *value = tmp;
        sem_post(sem);
    }
    else
    {
        // 父进程
        sem_wait(sem);
        int tmp = *value + 1;
        sleep(1);
        *value = tmp;
        // 等待子进程执行完毕
        sem_post(sem);
        waitpid(pid,NULL,0);
        printf("this is father, child finished\n");
        printf("the final value is %d\n", *value);

    }


    if(munmap(value, sizeof(int)) == -1)
    {
        perror("munmap value");
    }


    if(close(value_fd) == -1)
    {
        perror("close value_fd");
    }
    if(sem_close(sem) == -1)
    {
        perror("close sem");
    }
    // 6、释放共享内存对象
    if(pid > 0)
    {
        shm_unlink(shm_value_name);
        sem_unlink(sem_name);
    }

    return 0;
}
